#!/bin/bash

set -u

CONFIG="/etc/check_mk/gitea.conf"

#
# CheckMK states
#
OK=0
WARN=1
CRIT=2
UNKNOWN=3

if [[ ! -r "$CONFIG" ]]; then
    echo "${UNKNOWN} \"Gitea\" - Configuration file ${CONFIG} missing or unreadable"
    exit 0
fi

# shellcheck disable=SC1090
source "$CONFIG"

#
# Defaults
#
GITEA_URL="${GITEA_URL:-http://127.0.0.1:3000}"
GITEA_TOKEN="${GITEA_TOKEN:-}"
CHECK_UPDATES="${CHECK_UPDATES:-yes}"
GITEA_RELEASE_API="${GITEA_RELEASE_API:-https://api.github.com/repos/go-gitea/gitea/releases/latest}"

#
# Requirements
#
if ! command -v curl >/dev/null 2>&1; then
    echo "${UNKNOWN} \"Gitea\" - curl is not installed"
    exit 0
fi

if ! command -v jq >/dev/null 2>&1; then
    echo "${UNKNOWN} \"Gitea\" - jq is not installed"
    exit 0
fi

#
# curl options
#
CURL_OPTS=(
    --silent
    --show-error
    --fail
    --connect-timeout 3
    --max-time 8
)

#
# Gitea authentication
#
AUTH_ARGS=()

if [[ -n "$GITEA_TOKEN" ]]; then
    AUTH_ARGS=(
        --header "Authorization: token ${GITEA_TOKEN}"
    )
fi

#
# ---------------------------------------------------------------------------
# Gitea health / version
# ---------------------------------------------------------------------------
#

VERSION_RESPONSE="$(
    curl \
        "${CURL_OPTS[@]}" \
        "${AUTH_ARGS[@]}" \
        "${GITEA_URL%/}/api/v1/version" \
        2>/dev/null
)"

CURL_RC=$?

if [[ $CURL_RC -ne 0 || -z "$VERSION_RESPONSE" ]]; then
    echo "${CRIT} \"Gitea\" - API unavailable at ${GITEA_URL}"
    exit 0
fi

INSTALLED_VERSION="$(
    printf '%s' "$VERSION_RESPONSE" |
        jq -r '.version // empty' 2>/dev/null
)"

if [[ -z "$INSTALLED_VERSION" ]]; then
    echo "${CRIT} \"Gitea\" - API responded but no version was returned"
    exit 0
fi

echo "${OK} \"Gitea\" - API reachable, version ${INSTALLED_VERSION}"

#
# ---------------------------------------------------------------------------
# Update check
# ---------------------------------------------------------------------------
#

if [[ "$CHECK_UPDATES" != "yes" ]]; then
    echo "${OK} \"Gitea Update\" - Update check disabled, installed ${INSTALLED_VERSION}"
    exit 0
fi

RELEASE_RESPONSE="$(
    curl \
        "${CURL_OPTS[@]}" \
        --header "Accept: application/vnd.github+json" \
        --header "User-Agent: checkmk-gitea-local-check" \
        "$GITEA_RELEASE_API" \
        2>/dev/null
)"

CURL_RC=$?

if [[ $CURL_RC -ne 0 || -z "$RELEASE_RESPONSE" ]]; then
    echo "${UNKNOWN} \"Gitea Update\" - Installed ${INSTALLED_VERSION}, unable to query upstream release"
    exit 0
fi

LATEST_VERSION="$(
    printf '%s' "$RELEASE_RESPONSE" |
        jq -r '.tag_name // empty' 2>/dev/null |
        sed 's/^v//'
)"

if [[ -z "$LATEST_VERSION" ]]; then
    echo "${UNKNOWN} \"Gitea Update\" - Installed ${INSTALLED_VERSION}, upstream returned no release version"
    exit 0
fi

#
# Remove common suffixes that may appear in Gitea's version response.
#
# Examples:
#   1.27.2
#   1.27.2+gitea
#   1.27.2 built with GNU Make
#
INSTALLED_CLEAN="$(
    printf '%s' "$INSTALLED_VERSION" |
        grep -oE '^[0-9]+\.[0-9]+\.[0-9]+' |
        head -n1
)"

LATEST_CLEAN="$(
    printf '%s' "$LATEST_VERSION" |
        grep -oE '^[0-9]+\.[0-9]+\.[0-9]+' |
        head -n1
)"

if [[ -z "$INSTALLED_CLEAN" || -z "$LATEST_CLEAN" ]]; then
    echo "${UNKNOWN} \"Gitea Update\" - Unable to compare installed=${INSTALLED_VERSION} latest=${LATEST_VERSION}"
    exit 0
fi

#
# sort -V performs semantic-ish version ordering suitable for Gitea's
# major.minor.patch release numbers.
#
NEWEST="$(
    printf '%s\n%s\n' "$INSTALLED_CLEAN" "$LATEST_CLEAN" |
        sort -V |
        tail -n1
)"

if [[ "$INSTALLED_CLEAN" == "$LATEST_CLEAN" ]]; then

    echo "${OK} \"Gitea Update\" - Current version ${INSTALLED_CLEAN}"

elif [[ "$NEWEST" == "$LATEST_CLEAN" ]]; then

    echo "${WARN} \"Gitea Update\" - Update available: installed ${INSTALLED_CLEAN}, latest ${LATEST_CLEAN}"

else

    #
    # Installed version newer than upstream latest.
    # This can happen with prerelease/dev builds.
    #
    echo "${OK} \"Gitea Update\" - Installed ${INSTALLED_CLEAN} is newer than upstream stable ${LATEST_CLEAN}"

fi

exit 0